package com.wedistudio.android.framework.fetcher;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import android.util.Log;

import com.turbomanage.httpclient.BasicHttpClient;
import com.turbomanage.httpclient.HttpResponse;
import com.turbomanage.httpclient.ParameterMap;
import com.turbomanage.httpclient.RequestLogger;
import com.wedistudio.android.framework.pool.PoolActivateStrategy;
import com.wedistudio.android.framework.pool.PoolFactory;
import com.wedistudio.android.framework.pool.PoolMakeStrategy;
import com.wedistudio.android.framework.service.ServiceException;

public class BasicFetcher {

	static {
		PoolFactory.register(BasicFetcher.class,
				new PoolMakeStrategy<BasicFetcher>() {

					@Override
					public BasicFetcher make() {
						return new BasicFetcher();
					}
				}, new PoolActivateStrategy<BasicFetcher>() {

					@Override
					public void activate(BasicFetcher t) {
						t.clearCookies();
					}
				}, 0, 10);
	}

	public static HttpResponse get(URL url, Map<String, String> params) {
		BasicFetcher fetcher = null;

		try {
			String path = url.getFile().substring(0,
					url.getFile().lastIndexOf('/'));
			String base = url.getProtocol() + "://" + url.getHost() + path;
			String action = url.getFile().substring(
					url.getFile().lastIndexOf('/'));

			fetcher = PoolFactory.get(BasicFetcher.class);
			HttpResponse response = fetcher.doGet(base, action, params);
			checkResponse(response);
			return response;
		} catch (ServiceException e) {
			throw e;
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			PoolFactory.release(fetcher);
		}
	}

	public static HttpResponse post(URL url, Map<String, String> params) {
		BasicFetcher fetcher = null;

		try {
			String path = url.getFile().substring(0,
					url.getFile().lastIndexOf('/'));
			String base = url.getProtocol() + "://" + url.getHost() + path;
			String action = url.getFile().substring(
					url.getFile().lastIndexOf('/'));

			fetcher = PoolFactory.get(BasicFetcher.class);
			HttpResponse response = fetcher.doPost(base, action, params);
			checkResponse(response);
			return response;
		} catch (ServiceException e) {
			throw e;
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			PoolFactory.release(fetcher);
		}
	}

	private static void checkResponse(HttpResponse response) {
		int code = response.getStatus();
		if (code >= 200 && code < 300)
			return;

		throw new RuntimeException("Html code " + code + " for "
				+ response.getUrl());
	}

	// Set the timeout in milliseconds until a connection is established.
	private final int TIMEOUT_CONNECTION = 3000;
	// in milliseconds which is the timeout for waiting for data.
	private final int TIMEOUT_SOCKET = 3000;

	public BasicFetcher() {
		super();
	}

	public void clearCookies() {
	}

	private BasicHttpClient createHttpClient(String baseURL) {
		BasicHttpClient httpClient = new BasicHttpClient(baseURL);
		httpClient.setRequestLogger(new RequestLogger() {

			@Override
			public void logResponse(HttpResponse httpResponse) {
				Log.v("BasicFetcher", httpResponse.getBodyAsString());
			}

			@Override
			public void logRequest(HttpURLConnection urlConnection,
					Object content) throws IOException {
				Log.v("BasicFetcher", urlConnection.getURL().toString());
			}

			@Override
			public void log(String msg) {
				Log.v("BasicFetcher", msg);
			}

			@Override
			public boolean isLoggingEnabled() {
				return true;
			}
		});

		httpClient.setConnectionTimeout(TIMEOUT_CONNECTION);
		httpClient.setReadTimeout(TIMEOUT_SOCKET);
		return httpClient;
	}

	public HttpResponse doGet(String baseURL, String action,
			Map<String, String> params) {

		try {

			BasicHttpClient httpClient = createHttpClient(baseURL);

			ParameterMap getparams = httpClient.newParams();
			if (params.size() > 0) {
				for (Map.Entry<String, String> entry : params.entrySet()) {
					getparams.add(entry.getKey(), entry.getValue());
				}
			}

			return httpClient.get(action, getparams);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
	}

	public HttpResponse doPost(String baseURL, String action,
			Map<String, String> params) {

		try {
			BasicHttpClient httpClient = createHttpClient(baseURL);

			ParameterMap getparams = httpClient.newParams();
			if (params.size() > 0) {
				for (Map.Entry<String, String> entry : params.entrySet()) {
					getparams.add(entry.getKey(), entry.getValue());
				}
			}
			
			return httpClient.post(action, getparams);

		} catch (Exception e) {
			throw new ServiceException(e);
		}
	}
}
